home *** CD-ROM | disk | FTP | other *** search
/ Mac Power 1997 December / MACPOWER-1997-12.ISO.7z / MACPOWER-1997-12.ISO / AMUG / PROGRAMMING / Raven 1.2.sit / Raven 1.2 / Source / Foundation / OS / ZDialogUtils.cpp < prev    next >
Text File  |  1997-09-05  |  21KB  |  804 lines

  1. /*
  2.  *  File:       ZDialogUtils.h
  3.  *  Summary:       Handy dialog manager related routines.
  4.  *  Written by: Jesse Jones
  5.  *
  6.  *  Copyright ゥ 1996-1997 Jesse Jones. 
  7.  *    For conditions of distribution and use, see copyright notice in ZTypes.h  
  8.  *
  9.  *  Change History (most recent first):    
  10.  *
  11.  *         <4>     8/05/97    JDJ        DoNote, DoCaution, and DoStop use StandardAlert in OS 8.
  12.  *                                    Added DoSave and DoRevert.
  13.  *         <3>     8/01/97    JDJ        DefaultFilterProc uses IsCommandPeriod.
  14.  *         <2>     1/09/96    JDJ        DoNote, DoCaution, and DoStop use the Notification
  15.  *                                    Manager if the app is in the background.
  16.  *         <1>     5/06/96    JDJ        Created
  17.  */
  18.  
  19. #include <ZDialogUtils.h>
  20.  
  21. #include <Appearance.h>
  22. #include <CType.h>
  23. #include <Palettes.h>
  24. #include <Scrap.h>
  25.  
  26. #include <ZConstants.h>
  27. #include <ZDebug.h>
  28. #include <ZGestalt.h>
  29. #include <ZMiscUtils.h>
  30. #include <ZNotify.h>
  31. #include <ZProcess.h>
  32. #include <ZStringUtils.h>
  33.  
  34.  
  35. // ===================================================================================
  36. //    Internal Functions
  37. // ===================================================================================
  38.  
  39. //---------------------------------------------------------------
  40. //
  41. // IsAColorPort
  42. //
  43. //---------------------------------------------------------------
  44. static bool IsAColorPort(GrafPtr port = nil)
  45. {
  46.     if (port == nil)
  47.         GetPort(&port);
  48.         
  49.     return ((((CGrafPtr) port)->portVersion & (short) 0xC000)) == (short) 0xC000;
  50.  
  51.  
  52. //---------------------------------------------------------------
  53. //
  54. // GetGrayColor
  55. //
  56. //---------------------------------------------------------------
  57. static RGBColor GetGrayColor(GDHandle device = nil)
  58. {
  59.     if (device == nil) {
  60.         device = GetGDevice();
  61.         ASSERT(device != nil);
  62.     }
  63.         
  64.     RGBColor back = {0, 0, 0};
  65.     RGBColor gray = {65535, 65535, 65535};
  66.     
  67.     (void) GetGray(device, &back, &gray);
  68.     
  69.     return gray;
  70. }
  71.  
  72.  
  73. //---------------------------------------------------------------
  74. //
  75. // IsPushButton
  76. //
  77. //---------------------------------------------------------------
  78. static bool IsPushButton(DialogPtr dialog, short item)
  79. {
  80.     ASSERT(dialog != nil);
  81.     
  82.     bool isBtn = false;
  83.     
  84.     if (item >= 1 && item <= CountDITL(dialog)) {
  85.         short    itemType;
  86.         Handle    itemHandle;
  87.         Rect    itemRect;
  88.     
  89.         GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  90.         if (itemType > itemDisable)
  91.              itemType -= itemDisable;
  92.              
  93.         isBtn = itemType == ctrlItem + btnCtrl;
  94.     }
  95.         
  96.     return isBtn;
  97. }
  98.  
  99.  
  100. //---------------------------------------------------------------
  101. //
  102. // DashedLineProc    
  103. //
  104. //---------------------------------------------------------------
  105. static UserItemUPP sDashLineProc = nil;
  106.  
  107. static pascal void DashedLineProc(DialogPtr dialog, short item)
  108. {
  109.     TRect bounds = GetItemBounds(dialog, item);
  110.     
  111.     Pattern pat;
  112.     GetIndPattern(&pat, sysPatListID, 4);
  113.     FillRect(bounds, &pat);
  114. }
  115.  
  116.  
  117. //---------------------------------------------------------------
  118. //
  119. // DrawPictureAt
  120. //
  121. // Draws specified picture at specified point without scaling.
  122. //
  123. //---------------------------------------------------------------
  124. static void DrawPictureAt(PicHandle picHand, TPoint dstPoint)
  125. {
  126.     TRect dstRect;
  127.  
  128.     dstRect[topLeft] = dstPoint;
  129.     dstRect[botRight] = dstPoint + TRect((**picHand).picFrame).GetSize();
  130.  
  131.     DrawPicture(picHand, dstRect);
  132. }
  133.  
  134.  
  135. //---------------------------------------------------------------
  136. //
  137. // DrawPictProc    
  138. //
  139. // Draws a picture in a user item. If the picture is smaller than 
  140. // the user item it is centered within the user item.
  141. //
  142. //---------------------------------------------------------------
  143. static UserItemUPP     sDrawPictProc = nil;
  144. static PicHandle*    sPict = nil;
  145.  
  146. static pascal void DrawPictProc(DialogPtr dialog, short item)
  147. {
  148.     TRect itemRect = GetItemBounds(dialog, item);
  149.     TRect dstRect  = itemRect;
  150.     
  151.     EraseRect(itemRect);
  152.     if (sPict!= nil && *sPict != nil) {
  153.         TRect picFrame = (***sPict).picFrame;
  154.         TPoint delta = dstRect.GetSize() - picFrame.GetSize();
  155.         dstRect.Inset((short) (delta.h/2), (short) (delta.v/2));
  156.         
  157.         DrawPictureAt(*sPict, dstRect[topLeft]);
  158.         
  159.     } else {
  160.         dstRect.Inset(1, 1);
  161.         FillRect(dstRect, &qd.gray);
  162.     }
  163.     
  164.     dstRect.Inset(-1, -1);
  165.     FrameRect(dstRect);    
  166. }
  167.  
  168.  
  169. //---------------------------------------------------------------
  170. //
  171. // DrawDefaultOutline
  172. //
  173. //---------------------------------------------------------------
  174. static void DrawDefaultOutline(DialogPtr dptr)
  175. {
  176.     short item = GetDialogDefaultItem(dptr);
  177.     
  178.     if (item > 0 && (GetItemType(dptr, item) & (ctrlItem+btnCtrl)) != 0) {
  179.         PenState oldState;
  180.         GetPenState(&oldState);
  181.         
  182.         PenNormal();
  183.         PenSize(3, 3);
  184.         PenMode(srcCopy);
  185.  
  186.         TRect bounds = GetItemBounds(dptr, item);
  187.         bounds.Inset(-4, -4);
  188.         
  189.         if (!ItemIsEnabled(dptr, item))
  190.             if (IsAColorPort())
  191.                 ::RGBForeColor(&GetGrayColor());
  192.             else
  193.                 PenPat(&qd.gray);
  194.         
  195.         short buttonOval = (short) (2 + (bounds.bottom - bounds.top)/2);
  196.         FrameRoundRect(bounds, buttonOval, buttonOval);
  197.             
  198.         SetPenState(&oldState);
  199.     }
  200. }  
  201.  
  202. #pragma mark -
  203.  
  204. //---------------------------------------------------------------
  205. //
  206. // DefaultFilterProc
  207. //
  208. //---------------------------------------------------------------
  209. pascal Boolean DefaultFilterProc(DialogPtr dptr, EventRecord* event, short* item)
  210. {
  211.     bool handled = false;
  212.     
  213.     GrafPtr oldPort;
  214.     GetPort(&oldPort);
  215.     SetPort(dptr);
  216.     
  217.     // Set the cursor to the ibeam if we're over an editBox.
  218.     Point mouse;
  219.     GetMouse(&mouse);
  220.     short itemType = statText;
  221.     short itemNum = (short) (FindDialogItem(dptr, mouse) + 1);
  222.     if (itemNum > 0)
  223.         itemType = GetItemType(dptr, itemNum);
  224.     SetCursor(itemType == editText ? *GetCursor(iBeamCursor) : &qd.arrow);
  225.  
  226.     short defaultItem = GetDialogDefaultItem(dptr);
  227.     short cancelItem  = 2;                                // GetDialogCancelItem isn't working...
  228.         
  229.     // If it's an update event draw an outline around the default button.
  230.     if (event->what == updateEvt && defaultItem > 0)
  231.         if ((DialogPtr) event->message == dptr)
  232.             DrawDefaultOutline(dptr);
  233.  
  234.     // Handle keystrokes.
  235.     if (event->what == keyDown) {
  236.         char ch   = (char) (event->message & charCodeMask);
  237.         short key = (short) ((event->message & keyCodeMask) >> 8);
  238.         
  239.         bool defaultEnabled = IsPushButton(dptr, defaultItem) && ItemIsEnabled(dptr, defaultItem);
  240.         bool cancelEnabled  = IsPushButton(dptr, cancelItem) && ItemIsEnabled(dptr, cancelItem);
  241.         
  242.         // Map F2, F3, and F4 function keys to cmd X, C, and V.
  243.         switch (key) {
  244.             case kF2Key:
  245.                 event->modifiers |= cmdKey;
  246.                 key = 'x';
  247.                 break;
  248.             
  249.             case kF3Key:
  250.                 event->modifiers |= cmdKey;
  251.                 key = 'c';
  252.                 break;
  253.             
  254.             case kF4Key:
  255.                 event->modifiers |= cmdKey;
  256.                 key = 'v';
  257.                 break;
  258.         }            
  259.         
  260.         // Handle cmd X, C, and V.
  261.         if ((event->modifiers & cmdKey) != 0) {
  262.             switch (toupper(ch)) {
  263.                 case 'X':
  264.                     ZeroScrap();
  265.                     DialogCut(dptr);                // Note that these do nothing if the dialog has no edit box.
  266.                     if (TEToScrap() != noErr && !gMonkeyLives)
  267.                         SysBeep(1);
  268.                     handled = true;
  269.                     break;
  270.                                         
  271.                 case 'C':
  272.                     ZeroScrap();
  273.                     DialogCopy(dptr);
  274.                     if (TEToScrap() != noErr && !gMonkeyLives)
  275.                         SysBeep(1);
  276.                     handled = true;
  277.                     break;
  278.                                         
  279.                 case 'V':
  280.                     if (TEFromScrap() == noErr)
  281.                         DialogPaste(dptr);
  282.                     else if (!gMonkeyLives)
  283.                         SysBeep(1);
  284.                     handled = true;
  285.                     break;
  286.             }    
  287.             
  288.         // Handle return and escape keys.
  289.         } else if ((ch == kReturnChar || ch == kEnterChar) && defaultEnabled) {
  290.             *item = defaultItem;
  291.             FlashButton(dptr, *item);
  292.             handled = true;
  293.         
  294.         } else if ((ch == kTildeChar || key == kEscapeKey) && cancelEnabled) { 
  295.             *item = cancelItem;
  296.             FlashButton(dptr, *item);
  297.             handled = true;
  298.         }
  299.         
  300.         // Handle command-period.
  301.         if (!handled && cancelEnabled && IsCommandPeriod(*event)) {
  302.             *item = cancelItem;
  303.             FlashButton(dptr, *item);
  304.             handled = true;
  305.         }
  306.     }
  307.     
  308.     SetPort(oldPort);
  309.  
  310.     return handled;
  311. }
  312.  
  313. static ModalFilterProcPtr     sFilters[8] = {DefaultFilterProc};
  314. static int                    sNumFilters = 1;
  315.  
  316. //---------------------------------------------------------------
  317. //
  318. // DefaultFilter
  319. //
  320. //---------------------------------------------------------------
  321. pascal Boolean DefaultFilter(DialogPtr dptr, EventRecord* event, short* item)
  322. {
  323.     bool handled = false;
  324.     
  325.     GrafPtr oPort;
  326.     GetPort(&oPort);
  327.     
  328.     for (int index = 0; index < sNumFilters && !handled; index++)
  329.         handled = (sFilters[index])(dptr, event, item);
  330.         
  331.     SetPort(oPort);
  332.     
  333.     return handled;
  334. }
  335.  
  336.  
  337. //---------------------------------------------------------------
  338. //
  339. // SaveChangesFilter
  340. //
  341. //---------------------------------------------------------------
  342. pascal Boolean SaveChangesFilter(DialogPtr dptr, EventRecord* event, short* item)
  343. {
  344.     bool handled = false;
  345.         
  346.     if (event->what == keyDown) {
  347.         char ch = (char) toupper((char) (event->message & charCodeMask));
  348.         if (ch == 'S') { 
  349.             *item = 1;
  350.             handled = true;
  351.         } else if (ch == 'D') { 
  352.             *item = 3;
  353.             handled = true;
  354.         }
  355.         
  356.         if (handled) 
  357.             FlashButton(dptr, *item);
  358.     }
  359.     
  360.     if (!handled)
  361.         handled = DefaultFilter(dptr, event, item);
  362.     
  363.     return handled;
  364. }
  365.  
  366. //---------------------------------------------------------------
  367. //
  368. // DefaultYDFilter
  369. //
  370. //---------------------------------------------------------------
  371. pascal Boolean DefaultYDFilter(DialogPtr dptr, EventRecord* event, short* item, void* myData)
  372. {
  373.     #pragma unused(myData)
  374.     
  375.     bool handled = false;                    // Note that returning true dismisses the dialog.
  376.     
  377.     GrafPtr oPort;
  378.     GetPort(&oPort);
  379.     
  380.     for (int index = 0; index < sNumFilters && !handled; index++)
  381.         handled = (sFilters[index])(dptr, event, item);
  382.     
  383.     SetPort(oPort);
  384.     
  385.     return handled;
  386. }
  387.  
  388.  
  389. //---------------------------------------------------------------
  390. //
  391. // AddDialogFilter
  392. //
  393. //---------------------------------------------------------------
  394. void AddDialogFilter(ModalFilterProcPtr filter)
  395. {
  396.     ASSERT(filter != nil);
  397.     ASSERT(sNumFilters < 8);
  398.     
  399.     sFilters[sNumFilters++] = filter;
  400. }
  401.  
  402. #pragma mark -
  403.  
  404. //---------------------------------------------------------------
  405. //
  406. // DoAlert
  407. //
  408. //---------------------------------------------------------------
  409. short DoAlert(ResID id, ModalFilterProcPtr filter)
  410. {
  411.     RoutineDescriptor desc = BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, filter);
  412.     ModalFilterUPP theFilter = (ModalFilterUPP) &desc;
  413.  
  414.     InitCursor();
  415.     short item = Alert(id, theFilter);
  416.     DisposeRoutineDescriptor((UniversalProcPtr) theFilter);
  417.     
  418.     return item;
  419. }
  420.  
  421.  
  422. //---------------------------------------------------------------
  423. //
  424. // DoStandardAlert
  425. //
  426. //---------------------------------------------------------------
  427. static short DoStandardAlert(AlertType type, const string& errorStr, const string& supplementalStr, ResID id, ModalFilterProcPtr filter)
  428. {
  429.     ASSERT(filter != nil);
  430.      
  431.     short item = ok;
  432.     
  433.     string text = errorStr + "¥r¥r" + supplementalStr;
  434.  
  435. #if !DRAG_AND_DROP_APP                        // TNotify and StateBroadcaster are overkill for a simple d&d app
  436.     if (!UProcess::InFront()) {
  437.         TNotify* note = new TNotify(text);
  438.         note->Post();
  439.     
  440.     } else 
  441. #endif
  442.     {
  443.         InitCursor();
  444.  
  445.         RoutineDescriptor desc = BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, filter);
  446.         ModalFilterUPP theFilter = (ModalFilterUPP) &desc;
  447.  
  448.         if (UGestalt::hasAppearanceMgr) {
  449.             AlertStdAlertParamRec params;
  450.             params.movable       = true;
  451.             params.helpButton    = false;
  452.             params.filterProc    = theFilter;
  453.             params.defaultText   = (StringPtr) -1L;        // use default (ie "OK")
  454.             params.cancelText    = nil;
  455.             params.otherText     = nil;
  456.             params.defaultButton = 1;
  457.             params.cancelButton  = 0;
  458.             params.position      = kWindowAlertPositionParentWindowScreen;
  459.     
  460.             OSErr err = StandardAlert(type, StrToPStr(errorStr), StrToPStr(supplementalStr), ¶ms, &item);
  461.             ASSERT(err == noErr);                        // seems kind of pointless to throw
  462.     
  463.         } else {
  464.             ParamText(StrToPStr(text), "¥p", "¥p", "¥p");
  465.  
  466.             if (type == kAlertStopAlert)
  467.                 item = StopAlert(id, theFilter);
  468.                 
  469.             else if (type == kAlertNoteAlert)
  470.                 item = NoteAlert(id, theFilter);
  471.                 
  472.             else 
  473.                 item = CautionAlert(id, theFilter);
  474.         }
  475.         
  476.         DisposeRoutineDescriptor((UniversalProcPtr) theFilter);
  477.     }
  478.         
  479.     return item;
  480. }
  481.  
  482.  
  483. //---------------------------------------------------------------
  484. //
  485. // DoNote
  486. //
  487. //---------------------------------------------------------------
  488. short DoNote(const string& errorStr, const string& supplementalStr, ResID id, ModalFilterProcPtr filter)
  489. {
  490.     short item = DoStandardAlert(kAlertNoteAlert, errorStr, supplementalStr, id, filter);
  491.         
  492.     return item;
  493. }
  494.  
  495.  
  496. //---------------------------------------------------------------
  497. //
  498. // DoCaution
  499. //
  500. //---------------------------------------------------------------
  501. short DoCaution(const string& errorStr, const string& supplementalStr, ResID id, ModalFilterProcPtr filter)
  502. {
  503.     short item = DoStandardAlert(kAlertCautionAlert, errorStr, supplementalStr, id, filter);
  504.         
  505.     return item;
  506. }
  507.  
  508.  
  509. //---------------------------------------------------------------
  510. //
  511. // DoStop
  512. //
  513. //---------------------------------------------------------------
  514. short DoStop(const string& errorStr, const string& supplementalStr, ResID id, ModalFilterProcPtr filter)
  515. {
  516.     short item = DoStandardAlert(kAlertStopAlert, errorStr, supplementalStr, id, filter);
  517.         
  518.     return item;
  519. }
  520.  
  521.  
  522. //---------------------------------------------------------------
  523. //
  524. // DoSave
  525. //
  526. //---------------------------------------------------------------
  527. short DoSave(const string& fileName, ModalFilterProcPtr filter)
  528. {
  529.     ASSERT(filter != nil);
  530.      
  531.     short item = kSaveBtn;
  532.     
  533.     InitCursor();
  534.  
  535.     RoutineDescriptor desc = BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, filter);
  536.     ModalFilterUPP theFilter = (ModalFilterUPP) &desc;
  537.  
  538.     if (UGestalt::hasAppearanceMgr) {
  539.         AlertStdAlertParamRec params;
  540.         params.movable       = true;
  541.         params.helpButton    = false;
  542.         params.filterProc    = theFilter;
  543.         params.defaultText   = StrToPStr(LoadRavenString("Save (Button)"));
  544.         params.cancelText    = StrToPStr(LoadRavenString("Cancel (Button)"));
  545.         params.otherText     = StrToPStr(LoadRavenString("Don't Save (Button)"));
  546.         params.defaultButton = kSaveBtn;
  547.         params.cancelButton  = kCancelBtn;
  548.         params.position      = kWindowAlertPositionParentWindowScreen;
  549.  
  550.         string errorStr = LoadRavenString("File メ") + fileName + LoadRavenString("モ not saved.");
  551.         string supplementalStr = LoadRavenString("Changes made to the file メ") + fileName + LoadRavenString("モ will be discarded if this file is not saved. Do you want to save changes to this file before closing it?");
  552.         
  553.         OSErr err = StandardAlert(kAlertCautionAlert, StrToPStr(errorStr), StrToPStr(supplementalStr), ¶ms, &item);
  554.         ASSERT(err == noErr);                        // seems kind of pointless to throw
  555.  
  556.     } else {
  557.         ParamText(StrToPStr(fileName), "¥p", "¥p", "¥p");
  558.  
  559.         item = CautionAlert(kSaveChangesAlert, theFilter);
  560.     }
  561.     
  562.     DisposeRoutineDescriptor((UniversalProcPtr) theFilter);
  563.         
  564.     return item;
  565. }
  566.  
  567.  
  568. //---------------------------------------------------------------
  569. //
  570. // DoRevert
  571. //
  572. //---------------------------------------------------------------
  573. bool DoRevert(const string& fileName, ModalFilterProcPtr filter)
  574. {
  575.     ASSERT(filter != nil);
  576.      
  577.     short item = cancel;
  578.     
  579.     InitCursor();
  580.  
  581.     RoutineDescriptor desc = BUILD_ROUTINE_DESCRIPTOR(uppModalFilterProcInfo, filter);
  582.     ModalFilterUPP theFilter = (ModalFilterUPP) &desc;
  583.  
  584.     if (UGestalt::hasAppearanceMgr) {
  585.         AlertStdAlertParamRec params;
  586.         params.movable       = true;
  587.         params.helpButton    = false; 
  588.         params.filterProc    = theFilter;
  589.         params.defaultText   = (StringPtr) -1L;        // use default (ie "OK")
  590.         params.cancelText    = (StringPtr) -1L;        // use default (ie "Cancel")
  591.         params.otherText     = nil; 
  592.         params.defaultButton = cancel;
  593.         params.cancelButton  = 0;
  594.         params.position      = kWindowAlertPositionParentWindowScreen;
  595.  
  596.         string errorStr = LoadRavenString("Revert changes to file メ") + fileName + LoadRavenString("モ.");
  597.         string supplementalStr = LoadRavenString("Reverting file メ") + fileName + LoadRavenString("モ will discard all changes made to this file since you last saved it. Do you want to discard all changes to this file?");
  598.         
  599.         OSErr err = StandardAlert(kAlertCautionAlert, StrToPStr(errorStr), StrToPStr(supplementalStr), ¶ms, &item);
  600.         ASSERT(err == noErr);                        // seems kind of pointless to throw
  601.  
  602.     } else {
  603.         ParamText(StrToPStr(fileName), "¥p", "¥p", "¥p");
  604.  
  605.         item = CautionAlert(kConfirmRevertAlert, theFilter);
  606.     }
  607.     
  608.     DisposeRoutineDescriptor((UniversalProcPtr) theFilter);
  609.         
  610.     return item == ok;
  611. }
  612.  
  613. #pragma mark -
  614.  
  615. //---------------------------------------------------------------
  616. //
  617. // GetItemBounds
  618. //
  619. //---------------------------------------------------------------
  620. TRect GetItemBounds(DialogPtr dialog, short item)
  621. {
  622.     short    itemType;
  623.     Handle    itemHandle;
  624.     Rect    itemRect;
  625.  
  626.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  627.     
  628.     return itemRect;
  629. }
  630.  
  631.  
  632. //---------------------------------------------------------------
  633. //
  634. // GetItemType
  635. //
  636. //---------------------------------------------------------------
  637. short GetItemType(DialogPtr dialog, short item)
  638. {
  639.     short    itemType;
  640.     Handle    itemHandle;
  641.     Rect    itemRect;
  642.  
  643.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  644.     
  645.     return itemType;
  646. }
  647.  
  648.  
  649. //---------------------------------------------------------------
  650. //
  651. // ItemIsEnabled
  652. //
  653. //---------------------------------------------------------------
  654. bool ItemIsEnabled(DialogPtr dialog, short item)
  655. {
  656.     short    itemType;
  657.     Handle    itemHandle;
  658.     Rect    itemRect;
  659.  
  660.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  661.     
  662.     return (itemType & itemDisable) == false;
  663. }
  664.  
  665.  
  666. //---------------------------------------------------------------
  667. //
  668. // GetControl
  669. //
  670. //---------------------------------------------------------------
  671. ControlHandle GetControl(DialogPtr dialog, short item)
  672. {
  673.     ASSERT(dialog != nil);
  674.     ASSERT(item >= 1 && item <= CountDITL(dialog));
  675.  
  676.     short    itemType;
  677.     Handle    itemHandle;
  678.     Rect    itemRect;
  679.  
  680.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  681.     if (itemType > itemDisable)
  682.          itemType -= itemDisable;
  683.     ASSERT(itemType >= ctrlItem + btnCtrl && itemType <= ctrlItem + resCtrl);
  684.     
  685.     return (ControlHandle) itemHandle;
  686. }
  687.  
  688.  
  689. //---------------------------------------------------------------
  690. //
  691. // GetDStr
  692. //
  693. //---------------------------------------------------------------
  694. string GetDStr(DialogPtr dialog, short item)
  695. {
  696.     ASSERT(dialog != nil);
  697.     ASSERT(item >= 1 && item <= CountDITL(dialog));
  698.  
  699.     short    itemType;
  700.     Handle    itemHandle;
  701.     Rect    itemRect;
  702.     Str255    itemString;
  703.  
  704.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  705.     if (itemType > itemDisable)
  706.          itemType -= itemDisable;
  707.     ASSERT(itemType == statText || itemType == editText);
  708.     GetDialogItemText(itemHandle, itemString);
  709.     
  710.     return PStrToStr(itemString);
  711. }
  712.  
  713. #pragma mark -
  714.  
  715. //---------------------------------------------------------------
  716. //
  717. // SetUserProc
  718. //
  719. //---------------------------------------------------------------
  720. void SetUserProc(DialogPtr dialog, short item, UserItemUPP userProc)
  721. {
  722.     short    itemType;
  723.     Handle    itemHandle;
  724.     Rect    itemRect;
  725.  
  726.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  727.     ASSERT(itemType == userItem || itemType == userItem+itemDisable);
  728.     SetDialogItem(dialog, item, itemType, (Handle) userProc, &itemRect);
  729. }
  730.  
  731.  
  732. //---------------------------------------------------------------
  733. //
  734. // SetDashedLineProc
  735. //
  736. //---------------------------------------------------------------
  737. void SetDashedLineProc(DialogPtr dialog, short item)
  738. {
  739.     if (sDashLineProc == nil)
  740.         sDashLineProc = NewUserItemProc(DashedLineProc);
  741.         
  742.     SetUserProc(dialog, item, sDashLineProc);
  743. }
  744.  
  745.  
  746. //---------------------------------------------------------------
  747. //
  748. // SetDrawPictProc
  749. //
  750. //---------------------------------------------------------------
  751. void SetDrawPictProc(DialogPtr dialog, short item, PicHandle* pict)
  752. {
  753.     if (sDrawPictProc == nil)
  754.         sDrawPictProc = NewUserItemProc(DrawPictProc);
  755.     sPict = pict;
  756.         
  757.     SetUserProc(dialog, item, sDrawPictProc);
  758. }
  759.  
  760. #pragma mark -
  761.  
  762. //---------------------------------------------------------------
  763. //
  764. // SetDStr
  765. //
  766. //---------------------------------------------------------------
  767. void SetDStr(DialogPtr dialog, short item, const string& str)
  768. {
  769.     ASSERT(dialog != nil);
  770.     ASSERT(item >= 1 && item <= CountDITL(dialog));
  771.     
  772.     short    itemType;
  773.     Handle    itemHandle;
  774.     Rect    itemRect;
  775.  
  776.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  777.     if (itemType > itemDisable)
  778.          itemType -= itemDisable;
  779.     ASSERT(itemType == statText || itemType == editText);
  780.     SetDialogItemText(itemHandle, StrToPStr(str));
  781. }
  782.  
  783.  
  784. //---------------------------------------------------------------
  785. //
  786. // FlashButton
  787. //
  788. //---------------------------------------------------------------
  789. void FlashButton(DialogPtr dialog, short item)
  790. {
  791.     ASSERT(dialog != nil);
  792.     ASSERT(item >= 1 && item <= CountDITL(dialog));
  793.     ASSERT(IsPushButton(dialog, item));
  794.     
  795.     long ticks;
  796.     
  797.     ControlHandle control = GetControl(dialog, item);
  798.     HiliteControl(control, kControlButtonPart);
  799.     Delay(8, &ticks);
  800.     HiliteControl(control, 0);
  801. }
  802.  
  803.